#include "bsp_port.h"
#include "User_App.h"
#include "bsp_Timer.h"

#if 0
void bsp_uart_SendData(Bsp_Uart_t Uart, uint8_t *data, uint16_t datalen)
{
    USART_TypeDef *UART;
    uint32_t Channel;

    switch (Uart)
    {
    case BSP_UART1:
        UART = USART1;
        Channel = LL_DMA_CHANNEL_1;
        break;

    case BSP_UART2:
        UART = USART2;
        Channel = LL_DMA_CHANNEL_2;
        break;

        //    case BSP_UART3:
        //        UART = USART3;
        //        Channel = LL_DMA_CHANNEL_3;
        //        break;

        //    case BSP_UART4:
        //        UART = USART4;
        //        Channel = LL_DMA_CHANNEL_4;
        //        break;

    default:
        break;
    }

    LL_DMA_SetMemoryAddress(DMA1, Channel, (uint32_t)data);
    LL_DMA_SetDataLength(DMA1, Channel, datalen);
    LL_USART_EnableDMAReq_TX(UART);
    /* Enable DMA Channel Tx */
    LL_DMA_EnableChannel(DMA1, Channel);
}


/*  @brief  串口以DMA方式发送数据
    @param  *databuf
            要发送的数据
    @param  datalen
            数据长度
    @return 无
    @property 无
*/
void bsp_USART_DMA_SendBytes(uint8_t *Buf, uint16_t Len)
{
#if 1

#if EnReDe485Pin
    MX_485_TX_MODEL;
#endif
    while (LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_1)) // 检查DMA通道是否启用或禁用
        ;
    LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)Buf); // 告诉DMA它要发送数据的地址
    LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, Len);              // 告诉DMA它要发送的数据长度
    LL_USART_EnableDMAReq_TX(USART1);                               // 让USART开启DMA模式传输模式
    LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);                   // 启用DMA通道
#endif

    将下方代码放到串口初始化中
    LL_USART_EnableIT_RXNE(USART1);                                                                                   // 使能串口中断
    LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);                                                                       // 启用DMA传输完成中断�??
    LL_DMA_SetPeriphAddress(DMA1, LL_DMA_CHANNEL_1, LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_TRANSMIT)); // 配置DMA传输的目的地�??

    将下方代码放到DMA中断中
    if (LL_DMA_IsActiveFlag_TC1(DMA1)) // 获取通道的传输完成标志。这里的LL_DMA_IsActiveFlag_TC2需要根据配置填写
    {
        LL_DMA_ClearFlag_TC1(DMA1);                    // 清除通道的传输完成标志
        LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1); // 禁用DMA通道
        LL_USART_DisableDMAReq_TX(USART1);             // 禁用DMA模式传输
    }
}
#endif

/*  @brief  串口发送函数
    @param  Buf
            要发送的数组
    @param  length
            数据组的长度
    @return 无
    @property 非DMA方式
*/
void bsp_USART_SendBytes(uint8_t *Buf, uint8_t length)
{
    bsp_mDelay(5);
    for (uint8_t i = 0; i < length; i++)
    {
        while (LL_USART_IsActiveFlag_TC(USART1) != 1)
            ;
        LL_USART_TransmitData8(USART1, Buf[i]); // 发送数据
    }
    bsp_mDelay(2);
}

// 重定向 printf();打开魔法棒里的开关
int fputc(int ch, FILE *stream)
{
    while (!LL_USART_IsActiveFlag_TXE(USART1))
    {
        ;
    }
    LL_USART_TransmitData8(USART1, (uint8_t)ch);
    return ch;
}

// 定义延时函数
void bsp_Delay_us(uint32_t us)
{
    uint32_t ticks = us * (SystemCoreClock / 10000000); // 计算需要的SysTick时钟周期数
    SysTick->LOAD = ticks - 1;                          // 设置重载值
    SysTick->VAL = 0;                                   // 清空当前值
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;            // 开启SysTick计数器
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0)
        ;              // 等待计数完成
    SysTick->CTRL = 0; // 关闭SysTick计数器
}

// 看门狗喂狗
void bsp_IWDG_ReloadCounter(void)
{
#if IWDG_FLAG
    LL_IWDG_ReloadCounter(IWDG); // 喂狗
#endif
}
